﻿//----------------------------------------------------------------
// Desc: 
// Edit: ShowLong, http://blog.csdn.net/showlong
//
// Date Created: 2012-04-13
//
// Update Date : 
//
// Copyright (c) Fuel4D (http://www.fuel4d.com), All rights reserved.
//
//----------------------------------------------------------------
#pragma once


//----------------------------------------------------------------
// 用于内存池的自动书写宏
//----------------------------------------------------------------
#define FNEW_FUNC               const ACHAR* file, size_t line, const ACHAR* func, const ACHAR* name
#define FNEW_FUNC_API           const ACHAR* file, size_t line, const ACHAR* func
#define FNEW_PASS               file, line, func, name
#define FNEW_PASS_API           file, line, func
#define FNEW_INFO               _FFILEA_, _FLINEA_, _FFUNCA_


//----------------------------------------------------------------
// 从 Fuel4D 内存池中分配内存，该对象须从IFMemObject继承或者填写有FDECLARE_STRUCT宏。
// 使用方法：
//  // 类对象，需要对象框架的和多层继承，或者带有纯虚类，如IFNodeObject
//  class MyClass :public IFMemObject
//    {
//        FDECLARE_CLASS(MyClass)
//        MyClass(){}
//        MyClass(int k){}
//    }
//  // 不需要从IFMemObject继承的对象或者类，如需要存到文件中的结构体FVECTOR3
//    class MyClass
//    {
//        FDECLARE_STRUCT(MyClass)
//    }
//  // 有多层继承情况下的结构体，每一层都需要FDECLARE_STRUCT定义
//    struct MyStructBase
//    {
//        FDECLARE_STRUCT(MyStructBase)
//    }
//    struct MyStruct : public MyStructBase
//    {
//        FDECLARE_STRUCT(MyStruct)
//    }
//
//  // 使用示例
//  1. MyClass* p = FNew(MyClass);      // 默认构造
//  2. MyClass* p = FNew(MyClass)(k);   // 带参构造
//  3. FDel(p);         // 删除对象
//  4. MyClass* p = FNew(MyClass)[10];  // 分配数组
//  5. FDelArray(p);    // 删除数组对象
//  6. BYTE* p = FAlloc(BYTE, 10);  // 分配10个字节
//  7. FFree(p);        // 释放字节
//  8. int* p = FAlloc(int, 1);     // 分配一个整型指针
//  9. FFree(p);        // 释放指针
//  10.MyClass** p = FAlloc(MyClass*, 10);  // 分配二维数组
//  11.FFree(p); // 释放二维数组
//
//  // 查询内存使用情况
//  1. FMemDump(0, 1); // 默认输出接口，带调用堆栈
//  2. FMemDump(0, 0); // 默认输出接口，不带调用堆栈
//  // 查询指定条件的内存使用情况
//  struct CHECK_MEMORY
//  {
//      size_t size; // 只打印大小为此值的内存信息
//  }
//  struct MyOut : public IFMemoryDumper
//  {
//      virtual void DumpObject(void* addr, FMemoryNode* nd, FMemoryDumpCallStack* pc, DWORD_PTR ud)
//      {
//          CHECK_MEMORY* pcm = (CHECK_MEMORY*)ud;
//          if (nd->size == pcm)
//          {
//              // ... 输出此内存信息
//          }
//      }
//  }
//  MyOut mo;
//  CHECK_MEMORY cm;
//  FMemDump(&mo, &cm); // 自定义输出接口
//
//----------------------------------------------------------------
#define FNew(cls)               new(FNEW_INFO, cls::_StaticClassName())  cls
#define FNewAPI(cls)            new(FNEW_PASS_API, cls::_StaticClassName()) cls
#define FAlloc(t, n)            (t*)FMemAlloc(sizeof(t)*(n), FNEW_INFO, _FTA(#t))
#define FFree(p)                FMemFree((void*&)(p))
#define FRealloc(p, t, n)       (t*)FMemRealloc(p, sizeof(t)*(n), FNEW_INFO, _FTA(#t))
#define FMsize(p)               FMemSize(p)


//----------------------------------------------------------------
// placement 分配
//----------------------------------------------------------------
#define FNewPT(p, cls)          ::new(p) cls
#define FNewPP(p)               ::new(p)


//----------------------------------------------------------------
// 释放
//----------------------------------------------------------------
template < typename _Ty > FINLINE void FDel(_Ty*& p){ if (p) { delete p; p = 0; } }
template < typename _Ty > FINLINE void FDelArray(_Ty*& p){ if (p) { delete[] p; p = 0; } }
template < typename _Ty > FINLINE void FDelRelease(_Ty*& p){ if (p) { p->Release(); delete p; p = 0; } }
template < typename _Ty > FINLINE void FDelDestory(_Ty*& p){ if (p != 0) { p->Destroy(); delete p; p = 0; } }
template < typename _Ty > FINLINE void FRelease(_Ty*& p){ if (p != 0) { p->Release(); p = 0; } }
template < typename _Ty > FINLINE void FDestory(_Ty*& p){ if (p != 0) { p->Destroy(); p = 0; } }


//----------------------------------------------------------------
// 用于IFMemObjectNEW/DELETE操作符代码
//----------------------------------------------------------------
#define FDECLARE_NEW \
public:\
    FINLINE static void* operator new  (size_t size, FNEW_FUNC){ return FMemAlloc(size, FNEW_PASS); }\
    FINLINE static void* operator new[](size_t size, FNEW_FUNC){ return FMemAlloc(size, FNEW_PASS); }\
    FINLINE static void operator delete  (void* pm, FNEW_FUNC){ FFree(pm); }\
    FINLINE static void operator delete[](void* pm, FNEW_FUNC){ FFree(pm); }\
private:\
    FINLINE static void* operator new  (size_t size){ return FMemAlloc(size, FNEW_INFO, _FTA("<error>")); }\
    FINLINE static void* operator new[](size_t size){ return FMemAlloc(size, FNEW_INFO, _FTA("<error>")); }\
public:\
    FINLINE static void operator delete  (void* pm){ FFree(pm); }\
    FINLINE static void operator delete[](void* pm){ FFree(pm); }


//----------------------------------------------------------------
// 普通小结构体重载NEW/DELETE，提供给那些不需要从IFMemObject继承的对象
//----------------------------------------------------------------
#define FDECLARE_STRUCT(class_name) \
public:\
    FDECLARE_NEW;\
public:\
    static const ACHAR* _StaticClassName(){ return _FTA(#class_name); }


//----------------------------------------------------------------
// 从IFMemObject基类派生的最终层类对象实现
//----------------------------------------------------------------
#define FDECLARE_CLASS(class_name) \
public:\
    virtual const ACHAR* ClassName(){ return _StaticClassName(); }\
    virtual FIDHASH ClassHash(){ return (FIDHASH)(DWORD_PTR)&_StaticClassName; }\
    static const ACHAR* _StaticClassName(){ return _FTA(#class_name); }
